大家好,我是Leo
今天要來講解的如何在serializer 引用 serializer的其他種用法
OK~~~ Let's go now!!!
今天我們也是跟昨天一樣製作一個auth list內要包含的是users、user_certificate及user_photo的資訊,如果我們想直接取到fullName,及我們要將薪水以每5000元分為一個等級,該如何製作serializer,我們今天會使用另一種方式來達到顯示的效果。
概念圖如下(黃色的部份是我們希望回傳的欄位)
因為昨天確認過有無資料,這邊就不重複確認了我們直接進入到serializer的環節。
serializers/user_list_ser.py
from rest_framework import serializers
from website.models import (
Users,
User_Photo,
User_Certificates
)
class PhotoListSerializer(serializers.ModelSerializer):
class Meta:
model = User_Photo
exclude =('created_at','deleted_at')
class PhotoIdsSerializer(serializers.ModelSerializer):
class Meta:
model = User_Photo
fields = ('id',)
def to_representation(self, instance):
return instance.id
class CertificateListSerializer(serializers.ModelSerializer):
class Meta:
model = User_Certificates
exclude = ('created_at', 'deleted_at')
class CertificateIdsSerializer(serializers.ModelSerializer):
class Meta:
model = User_Certificates
exclude = ('created_at', 'deleted_at')
def to_representation(self, instance):
return instance.id
class UserListSecondWaySerializer(serializers.ModelSerializer):
userName = serializers.ReadOnlyField(source='auth_user.username')
email = serializers.ReadOnlyField(source='auth_user.email')
roleName = serializers.ReadOnlyField(source='role.name')
roleSalary = serializers.ReadOnlyField(source='role.salary')
fullName = serializers.SerializerMethodField()
userPhotos = serializers.SerializerMethodField()
userPhotosIds = serializers.SerializerMethodField()
userCertificates = serializers.SerializerMethodField()
userCertificateIds = serializers.SerializerMethodField()
class Meta:
model = Users
fields = ("id",
"status",
"userName",
"email",
"tel",
"roleName",
"roleSalary",
"fullName",
"userPhotosIds",
"userPhotos",
"userCertificateIds",
"userCertificates"
)
def get_userPhotos(self,instance):
userPhotos = instance.users.all().order_by("id")
return PhotoListSerializer(userPhotos, read_only=True, many=True).data
def get_userPhotosIds(self, instance):
userPhotosIds = instance.users.all().order_by("id")
return PhotoIdsSerializer(userPhotosIds, read_only=True, many=True).data
def get_userCertificateIds(self, instance):
userCertificateIds = instance.user_certicicate_users.all().order_by("id")
return CertificateIdsSerializer(userCertificateIds, read_only=True, many=True).data
def get_userCertificates(self, instance):
userCertificates = instance.user_certicicate_users.all().order_by("id")
return CertificateListSerializer(userCertificates, read_only=True, many=True).data
def get_fullName(self, instance):
name = instance.auth_user.last_name + instance.auth_user.first_name
return name
def to_representation(self,instance):
data = super().to_representation(instance)
data['roleSalaryLevel'] = dict(data)['roleSalary']//5000
return data
這邊有個重點,instance後的參數,需接當初在設計model時的related_name,以下是user_photo_model.py
get_field 用法需要跟上面的serializer定義的名稱一樣,也就是說 get_fullName 上面就需要有一個fullName的欄位,會接function回傳的資訊。
to_representation(self,instance) 可以改變序列化的輸出,透過super()繼承,增加一個欄位為roleSalaryLevel,等級為每5000元為一個等級
serializers/init.py
from .user_list_ser import *
views/user_list.py
from rest_framework import permissions
from rest_framework.views import APIView
from website.models import Users
from website.serializers import UserListSerializer,UserListSecondWaySerializer
from rest_framework.response import Response
class UserListAPIView(APIView):
permission_classes = (permissions.AllowAny,)
authentication_classes = []
def post(self, request):
users = Users.objects.all()
serializer_users = UserListSecondWaySerializer(
users, many=True, context={"request": request}
)
return Response(serializer_users.data)
views/init.py
from .user_list import *
urls.py
from django.urls import path
from website.views import UserListAPIView
path('api/user/list',UserListAPIView.as_view(),name='api-user-list')
json
[
{
"id": 1,
"status": 0,
"userName": "leo1",
"email": "a@gamil.com",
"tel": "0987654321",
"roleName": "parttime",
"roleSalary": 10000.0,
"fullName": "leeleo",
"userPhotosIds": [
1
],
"userPhotos": [
{
"id": 1,
"file_name": "lbj",
"file_path": "/media/users/1/4d27a17b-4965-4383-8373-6fba575e3096.jpg",
"user": 1
}
],
"userCertificateIds": [
1,
2
],
"userCertificates": [
{
"id": 1,
"file_name": "leo",
"file_path": "/media/users/1/c0c4adea-3f21-4011-a0a2-019eb92515a8.jpg",
"user": 1
},
{
"id": 2,
"file_name": "leo",
"file_path": "/media/users/1/110e6360-c3a1-4619-b855-282242a55c5e.jpg",
"user": 1
}
],
"roleSalaryLevel": 2.0
},
{
"id": 2,
"status": 0,
"userName": "leo",
"email": "a@gamil.com",
"tel": "0987654321",
"roleName": "parttime",
"roleSalary": 10000.0,
"fullName": "leeleo",
"userPhotosIds": [
3,
4
],
"userPhotos": [
{
"id": 3,
"file_name": "lin",
"file_path": "/media/users/2/e5316f6e-4410-4e93-a7f7-9bf5ff3831cc.jpg",
"user": 2
},
{
"id": 4,
"file_name": "lin",
"file_path": "/media/users/2/84854e94-eada-4940-b0d8-ea97ec25d41d.jpg",
"user": 2
}
],
"userCertificateIds": [
3
],
"userCertificates": [
{
"id": 3,
"file_name": "leo2",
"file_path": "/media/users/2/53f26df3-0213-4d02-aeb2-1e4a3c8816b6.jpg",
"user": 2
}
],
"roleSalaryLevel": 2.0
},
{
"id": 3,
"status": 0,
"userName": "leo2",
"email": "a@gamil.com",
"tel": "0987654321",
"roleName": "parttime",
"roleSalary": 10000.0,
"fullName": "lee2leo2",
"userPhotosIds": [
2
],
"userPhotos": [
{
"id": 2,
"file_name": "yun",
"file_path": "/media/users/3/6a5a0079-a2c3-4647-8ad0-0d1ba05afd5d.jpg",
"user": 3
}
],
"userCertificateIds": [],
"userCertificates": [],
"roleSalaryLevel": 2.0
},
{
"id": 4,
"status": 0,
"userName": "leo3",
"email": "a@gamil.com",
"tel": "0987654321",
"roleName": "engineer",
"roleSalary": 20000.0,
"fullName": "lee3leo3",
"userPhotosIds": [],
"userPhotos": [],
"userCertificateIds": [],
"userCertificates": [],
"roleSalaryLevel": 4.0
},
{
"id": 5,
"status": 0,
"userName": "leo4",
"email": "a@gamil.com",
"tel": "0987654321",
"roleName": "engineer",
"roleSalary": 20000.0,
"fullName": "lee4leo4",
"userPhotosIds": [],
"userPhotos": [],
"userCertificateIds": [],
"userCertificates": [],
"roleSalaryLevel": 4.0
},
{
"id": 6,
"status": 0,
"userName": "leo5",
"email": "a@gamil.com",
"tel": "0987654321",
"roleName": "manage",
"roleSalary": 30000.0,
"fullName": "lee5leo5",
"userPhotosIds": [],
"userPhotos": [],
"userCertificateIds": [],
"userCertificates": [],
"roleSalaryLevel": 6.0
}
]
透過這種方式也可以增減serializers的field,或自訂義field
今天透過serializer將我們要的fields欄位全部回傳回來,以及新增一個roleSalaryLevel field與定義一個fullName field,透過今天的方式,可以自行修改及增減serializers,是一個滿實用的分法
明天我想介紹的是如果我們有多個db,我們不可能一個專案for一個db,我們要同時使用ORM連接多個DB的方式
我們明天見,各位掰掰~~~